package com.example.transaction.service.impl;

import com.example.transaction.mapper.BMapper;
import com.example.transaction.pojo.B;
import com.example.transaction.service.BService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Service
public class BServiceImpl implements BService {
    @Autowired
    private BMapper bMapper;


    @Override
    public boolean insert(B b) {
        return bMapper.insertB(b);
    }
    @Override
    public boolean updateByName(String name, Integer money) {
        return bMapper.updateBByName(name,money);
    }
    @Override
    public B selectByName(String name) {
        return bMapper.selectBByName(name);
    }
    @Override
    public List<B> selectBll() {
        return bMapper.selectBAll();
    }


    /**
     * 只要是同一个事务或者子事务，无论哪个事务方法出错，都会使得整个事务回滚，即所有操作回滚。
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void REQUIRED(){
        System.out.println(bMapper.updateBByName("a", 10000));
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void REQUIRED_ERROR(){
        //不能使用try-catch,因为报错不触发回滚
//        try{
//            System.out.println(bMapper.updateBByName("a", 10000));
//            int i=10/0;
//        }catch (RuntimeException e){
//            System.out.println(e);
//        }
        System.out.println(bMapper.updateBByName("a", 10000));
        int i=10/0;
    }

    /**
     * 如果当前有事务，则==加入当前事务，即同一事务==，即哪个报错都会使得整个事务回滚，如果当前没有事务，
     * 就以==非事务方式执行，即每条sql语句的执行都是自动提交，出错也不会回滚。==
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public void SUPPORTS(){
        System.out.println(bMapper.updateBByName("a", 10000));
    }
    @Transactional(propagation = Propagation.SUPPORTS)
    public void SUPPORTS_ERROR(){
        System.out.println(bMapper.updateBByName("a", 10000));
        int i=10/0;
    }

    /**
     * 需要依赖jar,其装配的bean名为JtaTransactionManager，在AtomikosJtaConfiguration自动配置类中
     * 不会受到父类事务影响而回滚，自己也不会影响父类函数，出现异常后会自动回滚。
     */
    @Transactional(transactionManager = "transactionManager",propagation = Propagation.REQUIRES_NEW)
    public void REQUIRES_NEW(){
        System.out.println(bMapper.updateBByName("a", 10000));
    }
    @Transactional(transactionManager = "transactionManager",propagation = Propagation.REQUIRES_NEW)
    public void REQUIRES_NEW_ERROR(){
        try {
            System.out.println(bMapper.updateBByName("a", 10000));
            int i=10/0;
        }catch (RuntimeException e){
            System.out.println(e);
        }
        //注意：如果使用REQUIRES_NEW，则必须使用try-catch进行捕获，因为，这样才不会因报错，而不执行后面的代码
//        System.out.println(bMapper.updateBByName("a", 10000));
//        int i=10/0;
    }

    /**
     * 需要配置DataSourceTransactionManager，
     * 并设置nestedTransactionAllowed为true，才能开启PROPAGATION_NESTED
     */
    @Transactional(transactionManager = "transactionManager",propagation = Propagation.NESTED)
    public void PROPAGATION_NESTED(){
        System.out.println(bMapper.updateBByName("a", 10000));
    }
    /**
     * 如果不想影响父事务，那么可以使用try-catch
     */
    @Transactional(transactionManager = "transactionManager",propagation = Propagation.NESTED)
    public void PROPAGATION_NESTED_ERROR(){
        //这样有一个坏处，那就是子事务一旦出错，不会回滚子事务
        try {
            System.out.println(bMapper.updateBByName("a", 10000));
            int i=10/0;
        }catch (RuntimeException e){
            System.out.println(e);
        }
//        System.out.println(bMapper.updateBByName("a", 10000));
//        int i=10/0;
    }
}
